package com.googlecode.lookie.swing.tree.samples;

import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeNode;

import com.googlecode.lookie.swing.tree.model.DeferredTreeNode;
import com.googlecode.lookie.swing.tree.model.DeferredTreeNodeModel;
import com.googlecode.lookie.swing.tree.model.util.DeferredTreeNodeWillExpandListener;
import com.googlecode.lookie.swing.tree.navigation.Navigator;
import com.googlecode.lookie.swing.tree.render.LabelProviderTreeCellRenderer;
import com.googlecode.lookie.swing.tree.support.file.FileTreeNode;
import com.googlecode.lookie.swing.tree.support.file.FileTreeNodeLabelProvider;
import com.googlecode.lookie.swing.tree.support.file.FileTreeNodeProvider;

public class NavigatorSample
    implements ActionListener
{

    private Navigator navigator;

    private JTree tree;

    private NavigatorSample()
    {
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );

        final FileSystemTreeNode root = new FileSystemTreeNode( null, null );

        final FileSystemTreeNodeProvider provider = new FileSystemTreeNodeProvider();
        final FileTreeNodeLabelProvider labelProvider = new FileTreeNodeLabelProvider();

        tree = new JTree();

        navigator = new Navigator( tree, root )
        {

            @Override
            protected DefaultTreeModel newTreeModel( TreeNode root )
            {
                return new DeferredTreeNodeModel( root, provider );
            }

        };

        tree.setRootVisible( false );
        tree.setShowsRootHandles( true );

        tree.addTreeWillExpandListener( new DeferredTreeNodeWillExpandListener( new FileSystemTreeNodeProvider() ) );

        LabelProviderTreeCellRenderer renderer = new LabelProviderTreeCellRenderer( labelProvider );
        tree.setCellRenderer( renderer );

        JScrollPane scrollPane = new JScrollPane( tree );
        frame.getContentPane().add( scrollPane, BorderLayout.CENTER );

        frame.add( getButtonPanel(), BorderLayout.NORTH );

        frame.pack();
        frame.setVisible( true );
    }

    private JPanel getButtonPanel()
    {
        JPanel panel = new JPanel( new FlowLayout() );

        JButton btnGoInto = new JButton( "Go Into" );
        btnGoInto.addActionListener( this );

        JButton btnGoUp = new JButton( "Go Up" );
        btnGoUp.addActionListener( this );

        JButton btnGoHome = new JButton( "Go Home" );
        btnGoHome.addActionListener( this );

        panel.add( btnGoInto );
        panel.add( btnGoHome );
        panel.add( btnGoUp );

        return panel;
    }

    public void actionPerformed( ActionEvent e )
    {
        if ( e.getSource() instanceof JButton )
        {
            JButton button = (JButton) e.getSource();
            String text = button.getText();
            if ( text.equals( "Go Into" ) )
            {
                navigator.goTo( (TreeNode) tree.getSelectionPath().getLastPathComponent() );
            }
            else
            {
                if ( text.equals( "Go Up" ) )
                {
                    if ( navigator.canGoUp() )
                    {
                        navigator.goUp();
                    }
                }
                else
                {
                    if ( text.equals( "Go Home" ) )
                    {
                        navigator.goHome();
                    }
                }
            }
        }
    }

    private class FileSystemTreeNodeProvider
        extends FileTreeNodeProvider
    {

        @Override
        protected TreeNode createTreeNode( File file, TreeNode parent )
        {
            return new FileSystemTreeNode( file, parent );
        }

    }

    private class FileSystemTreeNode
        extends DeferredTreeNode
        implements FileTreeNode
    {

        private File file;

        public FileSystemTreeNode( File file, TreeNode parent )
        {
            super( parent );
            this.file = file;
        }

        public File getFile()
        {
            return file;
        }

    }

    public static void main( String[] args )
    {
        new NavigatorSample();
    }
}
